﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using SingleUserMall.Actives;
using SingleUserMall.Common;
using SingleUserMall.Items;
using SingleUserMall.Mall.Form;
using SingleUserMall.Mall.VO;
using SingleUserMall.Points;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleUserMall.Mall
{
    [AbpAuthorize]
    public class MallManageAppService : SingleUserMallAppServiceBase, IMallManageAppService
    {
        private readonly IRepository<Banner, long> _bannerRepository;
        private readonly IRepository<ItemCategory, long> _itemCategoryRepository;
        private readonly IRepository<Item, long> _itemRepository;
        private readonly IRepository<RecommendCategory, long> _recommendCategoryRepository;
        private readonly IRepository<PointRules, long> _pointRulesRepository;
        private readonly IRepository<ReleasePointRules, long> _releasePointRulesRepository;
        private readonly IRepository<Active, long> _activeRepository;
        public MallManageAppService(
            IRepository<Banner, long> bannerRepository,
            IRepository<ItemCategory, long> itemCategoryRepository,
            IRepository<Item, long> itemRepository,
            IRepository<RecommendCategory, long> recommendCategoryRepository,
            IRepository<PointRules, long> pointRulesRepository,
            IRepository<ReleasePointRules, long> releasePointRulesRepository,
            IRepository<Active, long> activeRepository
            )
        {
            _bannerRepository = bannerRepository;
            _itemCategoryRepository = itemCategoryRepository;
            _itemRepository = itemRepository;
            _recommendCategoryRepository = recommendCategoryRepository;
            _pointRulesRepository = pointRulesRepository;
            _releasePointRulesRepository = releasePointRulesRepository;
            _activeRepository = activeRepository;
        }
        public async Task<BannerVO> GetBannerAsync(SingleId<long> form)
        {
            var banner = await _bannerRepository.FirstOrDefaultAsync(form.Id);
            return banner.ToVO<Banner, BannerVO>();
        }

        public async Task<ListResultDto<BannerVO>> GetBannersAsync(HasStoreForm form)
        {
            var query = _bannerRepository.GetAll().Where(x => x.StoreId == form.StoreId)
                .OrderBy(x => x.Sort);
            return await query.ToListResultDtoAsync<Banner, BannerVO>();
        }

        public async Task<ListResultDto<ActiveVO>> GetActivesAsync()
        {
            var query = _activeRepository.GetAll()
                .OrderBy(x => x.Sort);
            return await query.ToListResultDtoAsync<Active, ActiveVO>();
        }

        public async Task MoveDownBannerAsync(SingleId<long> form)
        {
            var banner = await _bannerRepository.FirstOrDefaultAsync(form.Id);
            var downBanner = _bannerRepository.GetAll()
                .Where(x => x.StoreId == banner.StoreId && x.Sort > banner.Sort)
                .OrderBy(x => x.Sort)
                .FirstOrDefault();
            if (downBanner != null)
            {
                var sort = downBanner.Sort;
                downBanner.Sort = banner.Sort;
                banner.Sort = sort;
            }
            else
            {
                banner.Sort += 1;
            }
        }

        public async Task MoveUpBannerAsync(SingleId<long> form)
        {
            var banner = await _bannerRepository.FirstOrDefaultAsync(form.Id);
            var upBanner = _bannerRepository.GetAll()
                .Where(x => x.StoreId == banner.StoreId && x.Sort < banner.Sort)
                .OrderByDescending(x => x.Sort)
                .FirstOrDefault();
            if (upBanner != null)
            {
                var sort = upBanner.Sort;
                upBanner.Sort = banner.Sort;
                banner.Sort = sort;
            }
            else
            {
                banner.Sort -= 1;
            }
        }

        public async Task MoveDownActiveAsync(SingleId<long> form)
        {
            var active = await _activeRepository.FirstOrDefaultAsync(form.Id);
            var downActive = _activeRepository.GetAll()
                .Where(x => x.Sort > active.Sort)
                .OrderBy(x => x.Sort)
                .FirstOrDefault();
            if (downActive != null)
            {
                var sort = downActive.Sort;
                downActive.Sort = active.Sort;
                active.Sort = sort;
            }
            else
            {
                active.Sort += 1;
            }
        }

        public async Task MoveUpActiveAsync(SingleId<long> form)
        {
            var active = await _activeRepository.FirstOrDefaultAsync(form.Id);
            var upActive = _activeRepository.GetAll()
                .Where(x => x.Sort < active.Sort)
                .OrderByDescending(x => x.Sort)
                .FirstOrDefault();
            if (upActive != null)
            {
                var sort = upActive.Sort;
                upActive.Sort = active.Sort;
                active.Sort = sort;
            }
            else
            {
                active.Sort -= 1;
            }
        }

        public async Task RemoveBannerAsync(SingleId<long> form)
        {
            await _bannerRepository.DeleteAsync(x => x.Id == form.Id);
        }

        public async Task SaveBannerAsync(BannerForm form)
        {
            var banner = await _bannerRepository.FirstOrDefaultAsync(form.Id);
            if (banner != null)
            {
                banner = form.MapTo(banner);
                await _bannerRepository.UpdateAsync(banner);
            }
            else
            {
                banner = form.MapTo<Banner>();
                var lastBanner = _bannerRepository.GetAll()
                    .Where(x => x.StoreId == banner.StoreId)
                    .OrderByDescending(x => x.Sort)
                    .FirstOrDefault();
                if (lastBanner != null)
                    banner.Sort = lastBanner.Sort + 1;
                await _bannerRepository.InsertAsync(banner);
            }
        }

        public async Task SaveActiveAsync(ActiveForm form)
        {
            var active = await _activeRepository.FirstOrDefaultAsync(form.Id);
            if (active != null)
            {
                active = form.MapTo(active);
                await _activeRepository.UpdateAsync(active);
            }
            else
            {
                active = form.MapTo<Active>();
                var lastActive = _activeRepository.GetAll()
                    .OrderByDescending(x => x.Sort)
                    .FirstOrDefault();
                if (lastActive != null)
                    active.Sort = lastActive.Sort + 1;
                await _activeRepository.InsertAsync(active);
            }
        }

        public async Task SavePointRulesAsync(PointRuleForm form)
        {
            var pointRule = await _pointRulesRepository.FirstOrDefaultAsync(form.Id);
            if (pointRule != null)
            {
                pointRule = form.MapTo(pointRule);
                await _pointRulesRepository.UpdateAsync(pointRule);
            }
            else
            {
                pointRule = form.MapTo<PointRules>();
                await _pointRulesRepository.InsertAsync(pointRule);
            }
        }

        public async Task<ListResultDto<PointRulesVO>> GetPointRulesAsync()
        {
            var query = _pointRulesRepository.GetAll();
            return await query.ToListResultDtoAsync<PointRules, PointRulesVO>((v,vo)=>
            {
                vo.DirectUserRateView = ((int)(v.DirectUserRate * 100)).ToString()+"%";
                vo.VIPGroupRateView = ((int)(v.VIPGroupRate * 100)).ToString() + "%";
            });
        }

        public async Task SaveReleasePointRulesAsync(ReleasePointRuleForm form)
        {
            var releasePointRule = await _releasePointRulesRepository.FirstOrDefaultAsync(form.Id);
            if (releasePointRule != null)
            {
                releasePointRule = form.MapTo(releasePointRule);
                await _releasePointRulesRepository.UpdateAsync(releasePointRule);
            }
            else
            {
                releasePointRule = form.MapTo<ReleasePointRules>();
                await _releasePointRulesRepository.InsertAsync(releasePointRule);
            }
        }

        public async Task<ListResultDto<ReleasePointRulesVO>> GetReleasePointRulesAsync()
        {
            var query = _releasePointRulesRepository.GetAll();
            return await query.ToListResultDtoAsync<ReleasePointRules, ReleasePointRulesVO>((v,vo)=>
            {
                vo.NormalUserOwnBuyRateView = ((v.NormalUserOwnBuyRate * 100)).ToString() + "%";
                vo.SuperVIPUserOwnBuyRateView = ((v.SuperVIPUserOwnBuyRate * 100)).ToString() + "%";
                vo.VIPUserOwnBuyRateView = ((v.VIPUserOwnBuyRate * 100)).ToString() + "%";
                vo.DirectNormalUserToVIPRateView = ((v.DirectNormalUserToVIPRate * 100)).ToString() + "%";
                vo.DirectNormalUserToSuperVIPRateView = ((v.DirectNormalUserToSuperVIPRate * 100)).ToString() + "%";
                vo.DirectSuperVIPUserToNormalUserRateView = ((v.DirectSuperVIPUserToNormalUserRate * 100)).ToString() + "%";
                vo.DirectSuperVIPUserToSuperVIPRateView = ((v.DirectSuperVIPUserToSuperVIPRate * 100)).ToString() + "%";
                vo.DirectSuperVIPUserToVIPRateView = ((v.DirectSuperVIPUserToVIPRate * 100)).ToString() + "%";
                vo.DirectVIPGroupUserToSuperVIPRateView = ((v.DirectVIPGroupUserToSuperVIPRate * 100)).ToString() + "%";
            });
        }

        public async Task RemoveReleasePointAsync(SingleId<long> form)
        {
            await _releasePointRulesRepository.DeleteAsync(x => x.Id == form.Id);
        }
    }
}
